#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include <pthread.h>

/*
 * 局部锁的使用
 * 局部锁 + for循环创建线程的代码:
 *
 * 06-negative.cpp 的锁是局部的，为了把锁传递给每个线程，
 * 可以定义一个结构体ThreadData,存放着线程名与锁：
 */

using std::cout;
using std::endl;
int tickets = 100;

class ThreadData
{
public:
    ThreadData(const std::string&threadname, pthread_mutex_t *mutex_p)
        :threadname_(threadname),mutex_p_(mutex_p)
    {}
    ~ThreadData(){}
public:
    std::string threadname_;
    pthread_mutex_t *mutex_p_;
};
void* get_ticket(void* args)
{
    ThreadData*td = static_cast<ThreadData *>(args);
    while(true)
    {
        pthread_mutex_lock(td->mutex_p_);
        if(tickets>0)
        {
            usleep(11111);
            cout<<td->threadname_<<"正在抢票 : "<<tickets<<endl;
            tickets--;
            pthread_mutex_unlock(td->mutex_p_);
        }
        else
        {
            pthread_mutex_unlock(td->mutex_p_);
            break;//注意这里有break
        }

        #if 0
        // 抢完票还有其他工作
        usleep(1000);   // 形成订单给用户
        #endif
    }
    return nullptr;
}

int main()
{
 #define NUM 4
     pthread_mutex_t lock;
     pthread_mutex_init(&lock,nullptr);
     std::vector<pthread_t> tids(NUM);

     for(int i =0;i<NUM;i++)
     {
         char buffer[64];
         snprintf(buffer,sizeof(buffer),"thread %d",i+1);
         ThreadData *td = new ThreadData(buffer,&lock);
         pthread_create(&tids[i],nullptr,get_ticket,td);
     }
     for(const auto&tid:tids)
     {
        pthread_join(tid,nullptr);
     }

    pthread_mutex_destroy(&lock);
    return 0;
}

#if 0

此时的运行结果每次都是能够减到1，但是运行的速度也变慢了。
这是因为加锁和加锁的过程是多个线程串行执行的，程序变慢了.

同时这里看到每次都是只有一个线程在抢票，这是因为锁只规定互斥访问，
并没有规定谁来优先执行所以谁的竞争力强就谁来持有锁。

#endif
